﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Deeper.Common;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Xml;
namespace Deeper.DataAccess
{
	/// <summary>
	/// 自定义的连接字符串
	/// </summary>
	public class Connstring
	{
		public Lazy<DbProviderFactory> Factory { private set; get; }
		public string ConnectionString { set; get; }
		public string ProviderName { set; get; }

		public DbConnection CreateConnection()
		{
			DbConnection conn = Factory.Value.CreateConnection();
			conn.ConnectionString = ConnectionString;
			return conn;
		}


		public Connstring(string Name = null, string Path = null)
		{
			Factory = new Lazy<DbProviderFactory>(() => { return DbProviderFactories.GetFactory(ProviderName); });
			if (Name.IsNotNull())
				Load(Name, Path);
		}

		private static XmlDocument LoadConfigFile(ref string path)
		{
			if (path.IsNull()) path = System.AppDomain.CurrentDomain.BaseDirectory + "\\conn.config";

			if (!System.IO.File.Exists(path)) throw new HDbException("无法获取连接配置文件");
			XmlDocument doc = new XmlDocument();                 //获得配置文件的全路径 
			doc.Load(path);
			return doc;
		}

		/// <summary>
		/// 读取连接字符串
		/// </summary>
		/// <param name="strKey"></param>
		/// <param name="path"></param>
		public void Load(string strKey, string path = null)
		{

			XmlDocument doc = LoadConfigFile(ref path);
			XmlNodeList nodes = doc.GetElementsByTagName("add");//找出名称为“add”的所有元素 
			if (nodes.IsNull() || nodes.Count == 0) throw new HDbException("连接文件中无法找到任何连接字符串");
			XmlNode node = nodes.Cast<XmlNode>().Find(s => s.Attributes["name"].Value.ToLower() == strKey.ToLower());
			if (node.IsNull()) throw new HDbException("没有找到指定的连接字符串");

			ProviderName = node.Attributes["providerName"].Value;
			ConnectionString = node.Attributes["connectionString"].Value;

		}

		/// <summary>
		/// 保存连接字符串
		/// </summary>
		/// <param name="strKey"></param>
		/// <param name="path"></param>
		public void Save(string strKey, string path = null)
		{
			XmlDocument doc = LoadConfigFile(ref path);
			XmlNodeList nodes = doc.GetElementsByTagName("add");//找出名称为“add”的所有元素 
			XmlNode node = nodes.Cast<XmlNode>().Find(s => s.Attributes["name"].Value.ToLower() == strKey.ToLower());
			node.Attributes["connectionString"].Value = ConnectionString;
			node.Attributes["providerName"].Value = ProviderName;
			node.Attributes["name"].Value = strKey;
			//保存上面的修改 
			doc.Save(path);
			string CacheKey = "ConnectionString-" + strKey;
			//CacheKey.RemoveCache();
		}

	}

	public static class DataHelper
	{
		private static Random rnd = new Random();
		private static bool CheckStruct(Type type)
		{
			//当属性为结构时进行系列化
			if (type.IsValueType && !type.IsEnum && !type.IsPrimitive && !type.IsSerializable)
			{
				return true;
			}
			return false;
		}

		internal static string FormatValue(this object val)
		{
			if (val.IsNull())
			{
				return "null";
			}

			Type type = val.GetType();

			if (type == typeof(Guid))
			{
				return string.Format("'{0}'", val);
			}
			else if (type == typeof(DateTime))
			{
				return string.Format("'{0}'", ((DateTime)val).ToString("yyyy-MM-dd HH:mm:ss"));
			}
			else if (type == typeof(bool))
			{
				return ((bool)val) ? "1" : "0";
			}
			else if (val is Field)
			{
				return ((Field)val).Name;
			}
			else if (type.IsEnum)
			{
				return Convert.ToInt32(val).ToString();
			}
			else if (type.IsValueType)
			{
				return val.ToString();
			}
			else
			{
				string sqlvalue = val.ToString();
				return string.Format("N'{0}'", sqlvalue);
			}
		}

		internal static string MakeUniqueKey(int length, string prefix)
		{
			int prefixLength = prefix == null ? 0 : prefix.Length;

			string chars = "1234567890abcdefghijklmnopqrstuvwxyz";

			StringBuilder sb = new StringBuilder();
			if (prefixLength > 0)
			{
				sb.Append(prefix);
				sb.Append("_");
				prefixLength++;
			}

			int dupCount = 0;
			int preIndex = 0;
			for (int i = 0; i < length - prefixLength; ++i)
			{
				int index = rnd.Next(0, 35);
				if (index == preIndex)
				{
					++dupCount;
				}
				sb.Append(chars[index]);
				preIndex = index;
			}
			if (dupCount >= length - prefixLength - 2)
			{
				rnd = new Random();
				return MakeUniqueKey(length, prefix);
			}

			return sb.ToString();
		}
	}
}
